package com.han.demo.utils;

import com.han.demo.listenerdesignpattern.IFileListener;

import java.io.*;

/**
 * @author hanjl
 * @Description 文件工具类：文件读写，同时提供进度条提示的功能供使用者可选开启
 * @ClassName FileWriteUtil
 * @createTime 2021/11/17 16:23
 */
public class FileWriteUtil {

    /**
     * 进行文件读写的核心类，通过可选传入一个监听器接口，将方法内部的参数传递出去
     */

    private static void doWriteFile(String inPath, String putPath,
                                    IFileListener fileListener) throws IOException {
        //获取输入流
        FileInputStream fis = new FileInputStream(inPath);
        BufferedInputStream bis = new BufferedInputStream(fis);
        //定义输出流
        FileOutputStream fos = new FileOutputStream(putPath);
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        //定义读取缓存区
        int PAGE_SIZE = 100;
        byte[] bytes = new byte[PAGE_SIZE];
        //定义文件大小和读取量
        int fileSize = fis.available();
        int readSize = 0;
        while(true){
            //如果不足一缓存冲区数据，全部读出
            if(fileSize <= PAGE_SIZE){
                byte[] b = new byte[fileSize];
                bis.read(b);
                bos.write(b);
                break;
            }else if(fileSize < readSize + PAGE_SIZE){
                //如果是最后一个读取
                byte[] b = new byte[fileSize-readSize];
                bis.read(b);
                bos.write(b);
                break;
            }else{
                //中间分页读取
                bis.read(bytes);
                bos.write(bytes);
                readSize += PAGE_SIZE;
            }
            //定义一个IFileListener监听器模式获取fileSize和readSize传递出去给调用者
            if(null != fileListener){
                fileListener.getReadSize(fileSize,readSize);
            }
        }
        bos.flush();
        fis.close();
        fos.close();
    }

    /**
     * 提供不带监听器的重载方法
     **/
    public static void writeFile(String inPath, String putPath) throws IOException {
        doWriteFile(inPath,putPath,null);
    }
    /**
     * 提供带监听器的重载方法
     **/
    public static void writeFile(String inPath, String putPath, IFileListener fileListener)
            throws IOException {
        doWriteFile(inPath,putPath,fileListener);
    }

    /**
     * 测试文件读取
     * @param args
     */
    public static void main(String[] args) {
        try {
            FileWriteUtil.writeFile("C:\\Users\\hanjl\\Desktop\\密码.txt",
                    "C:\\Users\\hanjl\\Desktop\\密码8888.txt",
                    //类似放置一个监听器监听读写方法，实时获取所需的事件属性
                    new IFileListener(){
                        @Override
                        public void getReadSize(int fileSize, int readSize) {
                            Double rate = (double)readSize*100/fileSize;
                            System.out.println("当前进度条=" + rate + "%");
                        }
                    });
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}
